package com.clx.channelHandler.hander;

import com.clx.compress.CompressWrapper;
import com.clx.compress.Compressor;
import com.clx.compress.CompressorFactory;
import com.clx.enumeration.RequestType;
import com.clx.serialize.Serializer;
import com.clx.serialize.SerializerFactory;
import com.clx.transport.message.CrpcRequest;
import com.clx.transport.message.CrpcResponse;
import com.clx.transport.message.MessageFormatConstant;
import com.clx.transport.message.RequestPayload;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 * 4B magic（魔术值） ---》crpc.getBytes()
 * 1B version(版本) ---> 1
 * 2B header length 首部的长度
 * 4B full length 报文总长度
 * 1B serialize
 * 1B compress
 * 1B requestType
 * 8B requestId
 *
 * body
 * */

/**
 * 出站时，第一个经过的处理器
 * */
@Slf4j
public class CrpcResponseEncoder extends MessageToByteEncoder<CrpcResponse> {
    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, CrpcResponse crpcResponse, ByteBuf byteBuf) throws Exception {
        // 4个字节的魔术值
        byteBuf.writeBytes(MessageFormatConstant.MAGIC);
        // 1个字节的版本号
        byteBuf.writeByte(MessageFormatConstant.VERSION);
        // 2个字节的头部的长度
        byteBuf.writeShort(MessageFormatConstant.HEADER_LENGTH);
        //  总长度不清楚，不知道body的长度 writeIndex（写指针）
        byteBuf.writerIndex(byteBuf.writerIndex() + MessageFormatConstant.FULL_FIELD_LENGTH);
        // 3个类型
        byteBuf.writeByte(crpcResponse.getCode());
        byteBuf.writeByte(crpcResponse.getSerializeType());
        byteBuf.writeByte(crpcResponse.getCompressType());
        // 8字节的请求id
        byteBuf.writeLong(crpcResponse.getRequestId());
        byteBuf.writeLong(crpcResponse.getTimeStamp());


        // 1,对响应做序列化
        byte[] body = null;
        if (crpcResponse.getBody() != null) {
            Serializer serializer = SerializerFactory.getSerialze(crpcResponse.getSerializeType()).getSerializer();
            body = serializer.serialize(crpcResponse.getBody());

            // 2.压缩
            Compressor compressor = CompressorFactory.getCompressor(
                    crpcResponse.getCompressType()
            ).getCompressor();
            body = compressor.compress(body);
        }
        if (body != null){
            byteBuf.writeBytes(body);
        }
        int boodyLength = body == null ? 0 : body.length;
        // 重新处理报文的总长度
        // 先保存当前写指针的位置
        int writerIndex = byteBuf.writerIndex();
        // 将写指针的位置移动到总长度的位置上
        byteBuf.writerIndex(MessageFormatConstant.MAGIC.length + MessageFormatConstant.VERSION_LENGHT + MessageFormatConstant.HEADER_FIELD_LENGTH);
        byteBuf.writeInt(MessageFormatConstant.HEADER_LENGTH + body.length);

        // 将写指针归位
        byteBuf.writerIndex(writerIndex);

        if (log.isDebugEnabled()){
            log.debug("响应【{}】已经在服务端完成编码工作。",crpcResponse.getRequestId());
        }
    }


}
